package com.ysw.rpc.common.utils;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import com.ysw.rpc.common.constants.RpcConstants;

/**
 * @author YinShangwen
 * @since 2023/4/4 13:08
 */
public class KryoUtil {
    private static final ThreadLocal<Kryo> THREAD_LOCAL = ThreadLocal.withInitial(() -> {
        Kryo kryo = new Kryo();
        // 关闭注册行为
        kryo.setRegistrationRequired(false);
        // 关闭引用-防止循环引用的时候出错
        kryo.setReferences(false);
        return kryo;
    });

    /**
     * 编码
     *
     * @param o 希望编码的对象
     * @return bytes
     */
    public static byte[] encode(Object o) {
        Output output = new Output(256, RpcConstants.MAX_BUFFER_SIZE);
        THREAD_LOCAL.get().writeObject(output, o);
        return output.getBuffer();
    }

    /**
     * 解码
     *
     * @param bytes 编码的字节数组
     * @param clazz 希望解码得到类型的Class对象
     * @param <T>   泛型
     * @return 解码后的对象
     */
    public static <T> T decode(byte[] bytes, Class<T> clazz) {
        return THREAD_LOCAL.get().readObject(new Input(bytes), clazz);
    }

}
